package org.lc.stk.service.course;

import java.util.List;
import java.util.Optional;

import org.lc.stk.model.course.KnowledgePoint;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

/**
 * 知识点服务接口
 */
public interface KnowledgePointService {
    /**
     * 创建知识点
     *
     * @param courseId 课程ID
     * @param chapterId 章节ID
     * @param knowledgePoint 知识点信息
     * @param preKnowledgeIds 前置知识点ID列表（可选）
     * @return 创建的知识点
     */
    KnowledgePoint createKnowledgePoint(Integer courseId, Integer chapterId, 
                                      KnowledgePoint knowledgePoint, List<Integer> preKnowledgeIds);

    /**
     * 更新知识点信息
     *
     * @param id 知识点ID
     * @param knowledgePoint 更新的知识点信息
     * @param preKnowledgeIds 前置知识点ID列表（可选）
     * @return 更新后的知识点
     */
    KnowledgePoint updateKnowledgePoint(Integer id, KnowledgePoint knowledgePoint, 
                                      List<Integer> preKnowledgeIds);

    /**
     * 删除知识点
     *
     * @param id 知识点ID
     */
    void deleteKnowledgePoint(Integer id);

    /**
     * 根据ID获取知识点
     *
     * @param id 知识点ID
     * @return 知识点信息
     */
    Optional<KnowledgePoint> getKnowledgePointById(Integer id);

    /**
     * 获取课程的所有知识点
     *
     * @param courseId 课程ID
     * @return 知识点列表
     */
    List<KnowledgePoint> getKnowledgePointsByCourse(Integer courseId);

    /**
     * 获取章节的所有知识点
     *
     * @param chapterId 章节ID
     * @return 知识点列表
     */
    List<KnowledgePoint> getKnowledgePointsByChapter(Integer chapterId);

    /**
     * 搜索知识点
     *
     * @param courseId 课程ID
     * @param name 知识点名称（模糊匹配）
     * @param pageable 分页参数
     * @return 知识点分页信息
     */
    Page<KnowledgePoint> searchKnowledgePoints(Integer courseId, String name, Pageable pageable);

    /**
     * 获取知识点的直接前置知识点
     *
     * @param id 知识点ID
     * @return 前置知识点列表
     */
    List<KnowledgePoint> getPreKnowledgePoints(Integer id);

    /**
     * 获取知识点的直接后置知识点
     *
     * @param id 知识点ID
     * @return 后置知识点列表
     */
    List<KnowledgePoint> getNextKnowledgePoints(Integer id);

    /**
     * 检查知识点之间是否存在循环依赖
     *
     * @param knowledgePointId 当前知识点ID
     * @param preKnowledgeIds 要添加的前置知识点ID列表
     * @return 是否存在循环依赖
     */
    boolean hasCircularDependency(Integer knowledgePointId, List<Integer> preKnowledgeIds);

    /**
     * 移动知识点到指定章节
     *
     * @param id 知识点ID
     * @param targetChapterId 目标章节ID
     * @return 更新后的知识点
     */
    KnowledgePoint moveKnowledgePoint(Integer id, Integer targetChapterId);

    /**
     * 检查知识点是否可以被删除
     * （如果作为其他知识点的前置知识点，则不能删除）
     *
     * @param id 知识点ID
     * @return 是否可以删除
     */
    boolean canDelete(Integer id);

    /**
     * 复制知识点到指定章节
     * （会同时复制前置知识点关系）
     *
     * @param id 知识点ID
     * @param targetChapterId 目标章节ID
     * @return 新创建的知识点
     */
    KnowledgePoint copyKnowledgePoint(Integer id, Integer targetChapterId);
}